//
//  AISDeviceController.m
//  AISUPnP
//
//  Created by Ares on 1/26/15.
//  Copyright (c) 2015 Ares. All rights reserved.
//

#import "AISDeviceController.h"
#import "AISSSDPCommDef.h"
#import "AISSSDP.h"
#import "AISSSDPMessage.h"
#import "AISUPnPDevice.h"
#import "AISHTTPServer.h"
#import "AISRemoteDeviceAgent.h"


AISDeviceController *gDeviceController = nil;

@interface AISDeviceController() <AISSSDPDelegate, AISHTTPServerDelegate>
{
    AISUPnPDevice *localDevice;
    NSMutableArray *remoteDeviceAgents;
}
@end

@implementation AISDeviceController

+ (AISDeviceController *)sharedInstance
{
    if (nil == gDeviceController)
    {
        gDeviceController = [[AISDeviceController alloc] init];
    }
    return gDeviceController;
}

- (id)init
{
    self = [super init];
    if (nil != self)
    {
        [[AISSSDP sharedInstance] setDelegate:self];
        [[AISHTTPServer sharedInstance] setDelegate:self];
        localDevice = [[AISUPnPDevice alloc] init];
        remoteDeviceAgents = [[NSMutableArray alloc] initWithCapacity:0];
    }
    return self;
}

#pragma mark APIs for Other Program

- (void)search
{
    [[AISSSDP sharedInstance] search];
}

- (NSArray *)foundDevices
{
    return remoteDeviceAgents;
}

#pragma mark AISSSDPDelegate

- (void)ssdpReceivedMessage:(AISSSDPMessage *)message
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        switch (message.messageType)
        {
            case MT_SSDP_SEARCH:
            {
                NSLog(@"Search From: %@,%ld", message.fromHost, message.fromPort);
                // localDevice do something.
                break;
            }
            case MT_SSDP_NOTIFY:
            {
                NSLog(@"Notify From: %@,%ld", message.fromHost, message.fromPort);
                [self processAgentMessage:message];
                break;
            }
            case MT_SSDP_RESPONSE:
            {
                NSLog(@"Response From: %@,%ld", message.fromHost, message.fromPort);
                [self processAgentMessage:message];
                break;
            }
            default:
                break;
        }
    });
}

- (void)processAgentMessage:(AISSSDPMessage *)message
{
    @synchronized(remoteDeviceAgents)
    {
        AISRemoteDeviceAgent *processedAgent = nil;
        for (AISRemoteDeviceAgent *agent in remoteDeviceAgents)
        {
            if ([agent processMessage:message])
            {
                processedAgent = agent;
            }
        }
        
        if (NTS_SSDP_BYEBYE == message.notifySubType)
        {
            if (nil != processedAgent)
            {
                [remoteDeviceAgents removeObject:processedAgent];
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    if ([self.delegate respondsToSelector:@selector(deviceControllerDidDeviceRemoved:)])
                    {
                        [self.delegate deviceControllerDidDeviceRemoved:processedAgent];
                    }
                });
            }
            
            return;
        }
        
        if (nil == processedAgent)
        {
            AISRemoteDeviceAgent *newAgent = [[AISRemoteDeviceAgent alloc] initWithMessage:message];
            [remoteDeviceAgents addObject:newAgent];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(deviceControllerDidDeviceAdded:)])
                {
                    [self.delegate deviceControllerDidDeviceAdded:newAgent];
                }
            });
        }
    }
}

@end
